package com.woniu.service.idiom.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.constants.ErrorConstants;
import com.woniu.entity.Nuser;
import com.woniu.entity.RedPacketPool;
import com.woniu.entity.idiom.IdiomInfoEntity;
import com.woniu.entity.idiom.IdiomInviteRecEntity;
import com.woniu.entity.idiom.IdiomRedBeansRecEntity;
import com.woniu.exception.MyErrorException;
import com.woniu.mapper.idiom.IdiomInfoMapper;
import com.woniu.mapper.idiom.IdiomRedBeansRecMapper;
import com.woniu.service.NuserService;
import com.woniu.service.RedPacketPoolService;
import com.woniu.service.WechatService;
import com.woniu.service.idiom.IdiomInfoService;
import com.woniu.service.idiom.IdiomInviteRecService;
import com.woniu.service.idiom.IdiomRedBeansRecService;
import com.woniu.utils.RedisKeyLockUtils;
import com.woniu.utils.RedisUtil;
import com.woniu.utils.TokenUtil;
import com.woniu.vo.idiom.IdiomExamAnswerResp;
import com.woniu.vo.idiom.IdiomInfoRespDto;
import com.woniu.vo.idiom.MyInfoResp;
import com.woniu.vo.idiom.WithDrawResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


@Service("idiomInfoService")
public class IdiomInfoServiceImpl extends ServiceImpl<IdiomInfoMapper, IdiomInfoEntity> implements IdiomInfoService {
    private final static Logger logger = LoggerFactory.getLogger(IdiomInfoServiceImpl.class);


    @Autowired
    private IdiomRedBeansRecMapper idiomRedBeansRecMapper;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private NuserService nuserService;

    @Autowired
    private RedisUtil redisUtil;


    @Autowired
    private WechatService wechatService;

    @Autowired
    private IdiomInviteRecService idiomInviteRecService;
    @Autowired
    private RedisKeyLockUtils redisKeyLockUtils;

    @Override
    public IdiomInfoRespDto queryIdiomInfo() {
        //成语主信息
        int count = Integer.parseInt(this.count() + "");
        Random random = new Random();
        int randomNumber = random.nextInt(count) + 1;
        IdiomInfoEntity idiomInfoEntity = this.getById(randomNumber);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
        String currentTime = dateFormat.format(new Date());

        IdiomInfoRespDto respDto = new IdiomInfoRespDto();
        BeanUtils.copyProperties(idiomInfoEntity, respDto);

        respDto.setTime(currentTime);

        //String userId = tokenUtil.getUserId();
        String userId = "test";
        if (userId == null) {

        }
        //放入红豆
        Integer redCount = getRedBeansCount(userId);
        respDto.setRedBeansCount(redCount == null ? 0 : redCount);

        // 缓存获取今日是否答题
        int value = hasAnswer(userId);
        respDto.setHasAnswer(value);
        logger.info("queryIdiomInfo resp:{}", JSON.toJSONString(respDto));
        return respDto;
    }

    @Override
    public MyInfoResp my() {
        MyInfoResp resp = new MyInfoResp();
        //String userId = tokenUtil.getUserId();
        String userId = "test";
        Nuser nuser = nuserService.getById(userId);
        if (nuser == null) {
            return resp;
        }
        // 缓存获取今日是否答题
        int value = hasAnswer(userId);

        SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd");
        String key = "idiom:today:read:" + temp.format(new Date()) + ":" + userId;
        int read = StrUtil.isBlank(redisUtil.getString(key)) ? 0 : 1;

        Integer redCount = getRedBeansCount(userId);
        resp.setCount(redCount == null ? 0 : redCount);
        resp.setHasRead(read);
        resp.setHasAnswer(value);
        // 邀请好友数量
        int count = Integer.parseInt(idiomInviteRecService.count(new QueryWrapper<IdiomInviteRecEntity>()
                .eq("from_uid", userId)
        ) + "");
        count = count > 5 ? 5 : count;
        resp.setInvite(Integer.parseInt(count + ""));

        //是否有邀请奖励
        String inviteKey = "idiom:share:" + userId;
        String countKey = inviteKey + ":count";
        boolean flag = false;
        IdiomExamAnswerResp inviteResp = new IdiomExamAnswerResp();
        if (redisUtil.exists(inviteKey)) {
            inviteResp.setIcon("");
            inviteResp.setMainTitle("恭喜你，获得红豆");
            String str = "成功邀请x位好友答题";
            //查询奖励次数
            if (redisUtil.exists(countKey)) {
                // 存在 - 比较次数差距
                int curCount = Integer.parseInt(redisUtil.get(countKey));
                if (count > curCount) {
                    inviteResp.setSecondaryTitle(String.format(str, count - curCount));
                    inviteResp.setCount(30 * count - curCount);
                    flag = true;
                }

            } else {
                // 不存在-
                if (count > 0) {
                    inviteResp.setSecondaryTitle(String.format(str, count));
                    inviteResp.setCount(30 * count);
                    flag = true;
                }
            }
        }
        if (flag) {
            resp.setInviteAward(inviteResp);
            redisUtil.setPermanentString(countKey, count + "");
        }

        return resp;
    }

    @Override
    public WithDrawResp withdraw() {

        String userId = tokenUtil.getUserId();
        Boolean isLock = redisKeyLockUtils.tryLock(userId, userId, 10000);
        WithDrawResp resp = new WithDrawResp();
        // 查询用户
        if (isLock) {
            try {
                Nuser nuser = nuserService.getById(userId);
                Integer count = getRedBeansCount(userId);

                if (count == null || count / 100 < 1) {
                    resp.setCode(1);
                    resp.setMsg("最少100个红豆方可提现");
                    return resp;
                }
                // 获取可提现红豆数量
                int canCount = (count / 100) * 100;
                // 金额 分
                wechatPayAsync(nuser.getOpenid(), canCount);
                // 写表
                IdiomRedBeansRecEntity entity = new IdiomRedBeansRecEntity();
                entity.setUid(userId);
                entity.setBeansCount(-canCount);
                entity.setType("红豆提现");
                idiomRedBeansRecMapper.insert(entity);

                resp.setCode(0);
                resp.setMsg("已提现至您的微信账户，请查收。如有延迟，请耐心等待");

            } finally {
                redisKeyLockUtils.releaseLuaLock(userId, userId);
            }
        }
        return resp;
    }

    private int hasAnswer(String userId) {
        // 缓存获取今日是否答题
        SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd");
        int value = StrUtil.isBlank(redisUtil.getString("idiom:today:answer:" + temp.format(new Date()) + ":" + userId)) ? 0 : 1;
        return value;
    }

    private Integer getRedBeansCount(String userId) {

        Nuser nuser = nuserService.getById(userId);
        if (nuser == null) {
            return null;
        }
        Integer count = idiomRedBeansRecMapper.redBeansCount(userId);
        logger.info("getRedBeansCount uid:{}, count:{}", userId, count);
        return count;
    }

    @Async
    public void wechatPayAsync(String openid, Integer money) {
        // 商户批次号
        String outBatchNo = new SimpleDateFormat("yyyyMMddHHmm").format(new Date()) + IdUtil.getSnowflake(0, 0).nextIdStr();
        //处理金额
        //Integer money = Integer.valueOf(String.valueOf(moneyD * 100).replace(".0", ""));

        // 转账
        wechatService.transferAccounts(outBatchNo, money, openid);
    }
}